Skip to content

Conversation

Pankraz76
Copy link

@Pankraz76 Pankraz76 commented Sep 29, 2025


I hereby agree to the terms of the JUnit Contributor License Agreement.


Definition of Done

Links:

@Pankraz76 Pankraz76 changed the title add refaster-runner Add error-prone.picnic.tech Oct 3, 2025
@Pankraz76 Pankraz76 marked this pull request as ready for review October 3, 2025 21:45
@Pankraz76 Pankraz76 changed the title Add error-prone.picnic.tech Add error-prone.picnic.tech covering S1488: Local variables should not be declared and then immediately returned or thrown Oct 3, 2025
@Pankraz76 Pankraz76 force-pushed the extend-errorprone branch 2 times, most recently from cb987d5 to c36f592 Compare October 4, 2025 15:02
Copy link
Author

@Pankraz76 Pankraz76 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2ct.

// The findings of this check are subjective because a named constant can be more readable in many cases
"UnnecessaryLambda",

// Resolving findings for these checks requires ErrorProne's annotations which we don't want to use
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assumed this is for the whole block as the block is some kind of pattern here but its a nice trap, assuming the comment only regards to AnnotateFormatMethod.

"MissingSummary",
"BadImport", // This check is opinionated wrt. which method names it considers unsuitable for import which includes a few of our own methods in `ReflectionUtils` etc.
"UnnecessaryLambda", // The findings of this check are subjective because a named constant can be more readable in many cases.
"AnnotateFormatMethod", // We don't want to use ErrorProne's annotations.
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

inline this is an clear intent and not an obsolete question.

sb.append(NL);
// Use the same prefix as java.lang.Throwable.printStackTrace(PrintStreamOrWriter)
sb.append("\tat ");
sb.append(stackTraceElement.toString());
Copy link
Author

@Pankraz76 Pankraz76 Oct 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assuming RedundantStringEscape is the fix.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you change this class manually or by applying a patch?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This patch is error-prone — it depends on the library’s behavior instead of individual, opinionated interpretation.
It would probably still pass the build even if reverted, which is exactly what we want to avoid. The setup isn’t really complete yet, and we’re still aiming for the proper rewrite equivalent.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

works as expected, failing the build on corruption:

meaning on cloud, when if local fixes are active, but not pushed, it will fail in the quality gate.

still this is kind of wack having to know the trick about the custom env, but okey.

Rewrite directly outputs the command how to apply the suggested/enforced change upfront.

11:18:41: Executing 'assemble clean'…

Starting Gradle Daemon...
Gradle Daemon started in 1 s 213 ms
> Task :junit-jupiter-api:javadoc FROM-CACHE

> Task :junit-jupiter-engine:compileJava
/Users/vincent.potucek/IdeaProjects/junit-framework/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/extension/PreInterruptThreadDumpPrinter.java:52: warning: [RedundantStringConversion] Avoid redundant string conversions when possible
					sb.append(stackTraceElement.toString());
					         ^
    (see https://error-prone.picnic.tech/bugpatterns/RedundantStringConversion)
  Did you mean 'sb.append(stackTraceElement);'?

> Task :junit-platform-console:compileJava
> Task :junit-platform-console:classes
> Task :junit-jupiter-api:javadocJar
> Task :junit-jupiter-api:assemble

> Task :junit-jupiter-engine:compileJava FAILED
error: warnings found and -Werror specified
1 error
1 warning

> Task :junit-platform-console:shadowJar

[Incubating] Problems report is available at: file:///Users/vincent.potucek/IdeaProjects/junit-framework/build/reports/problems/problems-report.html

Deprecated Gradle features were used in this build, making it incompatible with Gradle 10.

You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.

For more on this, please refer to https://docs.gradle.org/9.1.0/userguide/command_line_interface.html#sec:command_line_warnings in the Gradle documentation.
135 actionable tasks: 77 executed, 11 from cache, 47 up-to-date

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':junit-jupiter-engine:compileJava'.
> Compilation failed; see the compiler output below.
  /Users/vincent.potucek/IdeaProjects/junit-framework/junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/extension/PreInterruptThreadDumpPrinter.java:52: warning: [RedundantStringConversion] Avoid redundant string conversions when possible
  					sb.append(stackTraceElement.toString());
  					         ^
      (see https://error-prone.picnic.tech/bugpatterns/RedundantStringConversion)
    Did you mean 'sb.append(stackTraceElement);'?
  1 error
  1 warning

BUILD FAILED in 59s
11:19:40: Execution finished 'assemble clean'.

@Pankraz76 Pankraz76 requested a review from marcphilipp October 4, 2025 15:08
@Pankraz76 Pankraz76 force-pushed the extend-errorprone branch 2 times, most recently from 8132ffc to 3337a15 Compare October 4, 2025 16:14
@Pankraz76 Pankraz76 changed the title Add error-prone.picnic.tech covering S1488: Local variables should not be declared and then immediately returned or thrown Add error-prone.picnic.tech Oct 4, 2025
errorproneArgs.add("-XepOpt:Refaster:NamePattern=^(?!.*Rules\\$).*") // might consider.
if (getenv("IN_PLACE").toBoolean()) {
errorproneArgs.addAll(
"-XepPatchLocation:IN_PLACE", // why only certain picnic rules apply?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does it know where to find the source files to patch? Does patching actually work? This comment suggests otherwise: tbroyer/gradle-errorprone-plugin#38 (comment)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It compiles, which means it’s quite involved and includes all the necessary information, producing output without any errors. Some of the changes might be critical, so it’s recommending to review the automatically generated modifications — just as rewrite advises — since these are machine suggestions and not guaranteed to be perfect. Double-checking is always necessary.

That’s why this feature is opt-in. It’s designed to catch issues, highlight them, and allow to fix the build with a single simple command. Just like check and spot have evolved to.

options.errorprone {
allErrorsAsWarnings = true
disableWarningsInGeneratedCode = true
errorproneArgs.add("-XepOpt:Refaster:NamePattern=^(?!.*Rules\\$).*") // might consider.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does this do?

Copy link
Author

@Pankraz76 Pankraz76 Oct 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ignore all Refaster Rules for now, as we fail many of them and maintaining a whitelist is too costly.

This means we’ll ignore all rules by default and selectively activate specific ones when needed. Since Refaster rules are not applied automatically by the autofix process, it’s not practical to enforce them at scale.

While rewrite can apply them as shown, error-prone should ideally be able to do the same — so this might just be a configuration or bug issue.

We could fix issues locally using rewrite and then activate Picnic, though that’s quite a hack. You mentioned it’s not allowed to be part of the main pipeline, but we could still integrate it without enabling it. This way, I get my rewrite integration, and you still maintain the rejection of it since it’s not actively applied in the change.

In a sense, this creates a kind of technical "detour," but one could argue that rewrite acts as a refactoring tool that goes beyond even what error-prone can do. At the end, we would benefit from both: rewrite can cover Refaster rules from Picnic (but not all bug patterns), while error-prone focuses on bug patterns. Each tool has its own benefits. One could also see rewrite as a "big brother" running in the cloud, and error-prone as the fast, local feedback tool.

This approach could help address JavaUtilAPIs changes and Java migrations that error-prone doesn’t cover, while still improving the overall codebase and developer experience.

sb.append(NL);
// Use the same prefix as java.lang.Throwable.printStackTrace(PrintStreamOrWriter)
sb.append("\tat ");
sb.append(stackTraceElement.toString());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you change this class manually or by applying a patch?

Copy link
Author

@Pankraz76 Pankraz76 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for the effort spend.

sb.append(NL);
// Use the same prefix as java.lang.Throwable.printStackTrace(PrintStreamOrWriter)
sb.append("\tat ");
sb.append(stackTraceElement.toString());
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This patch is error-prone — it depends on the library’s behavior instead of individual, opinionated interpretation.
It would probably still pass the build even if reverted, which is exactly what we want to avoid. The setup isn’t really complete yet, and we’re still aiming for the proper rewrite equivalent.

errorproneArgs.add("-XepOpt:Refaster:NamePattern=^(?!.*Rules\\$).*") // might consider.
if (getenv("IN_PLACE").toBoolean()) {
errorproneArgs.addAll(
"-XepPatchLocation:IN_PLACE", // why only certain picnic rules apply?
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It compiles, which means it’s quite involved and includes all the necessary information, producing output without any errors. Some of the changes might be critical, so it’s recommending to review the automatically generated modifications — just as rewrite advises — since these are machine suggestions and not guaranteed to be perfect. Double-checking is always necessary.

That’s why this feature is opt-in. It’s designed to catch issues, highlight them, and allow to fix the build with a single simple command. Just like check and spot have evolved to.

Copy link
Author

@Pankraz76 Pankraz76 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ready to go.


@Option(names = {
"--exclude-package" }, paramLabel = "PKG", arity = "1", description = "Provide a package to be excluded from the test run. This option can be repeated.")
@Option(names = "--exclude-package", paramLabel = "PKG", arity = "1", description = "Provide a package to be excluded from the test run. This option can be repeated.")
Copy link
Author

@Pankraz76 Pankraz76 Oct 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactoring changes were successfully applied to file:///Users/vincent.potucek/IdeaProjects/junit-framework/junit-platform-console/src/main/java/org/junit/platform/console/options/TestDiscoveryOptionsMixin.java, please check the refactored code and recompile.
> Task :junit-platform-console-standalone:classes UP-TO-DATE
/Users/vincent.potucek/IdeaProjects/junit-framework/junit-platform-console/src/main/java/org/junit/platform/console/options/TestDiscoveryOptionsMixin.java:158: Note: [CanonicalAnnotationSyntax] Omit redundant syntax from annotation declarations
		@Option(names = {
		^
    (see https://error-prone.picnic.tech/bugpatterns/CanonicalAnnotationSyntax)
  Did you mean '@Option(names = "--include-package", paramLabel = "PKG", arity = "1", description = "Provide a package to be included in the test run. This option can be repeated.")'?
/Users/vincent.potucek/IdeaProjects/junit-framework/junit-platform-console/src/main/java/org/junit/platform/console/options/TestDiscoveryOptionsMixin.java:162: Note: [CanonicalAnnotationSyntax] Omit redundant syntax from annotation declarations
		@Option(names = {
		^
    (see https://error-prone.picnic.tech/bugpatterns/CanonicalAnnotationSyntax)
  Did you mean '@Option(names = "--exclude-package", paramLabel = "PKG", arity = "1", description = "Provide a package to be excluded from the test run. This option can be repeated.")'?
/Users/vincent.potucek/IdeaProjects/junit-framework/junit-platform-console/src/main/java/org/junit/platform/console/options/TestDiscoveryOptionsMixin.java:166: Note: [CanonicalAnnotationSyntax] Omit redundant syntax from annotation declarations
		@Option(names = {
		^
    (see https://error-prone.picnic.tech/bugpatterns/CanonicalAnnotationSyntax)
  Did you mean '@Option(names = "--include-methodname", paramLabel = "PATTERN", arity = "1", description = "Provide a regular expression to include only methods whose fully qualified names without parameters match. "'?
/Users/vincent.potucek/IdeaProjects/junit-framework/junit-platform-console/src/main/java/org/junit/platform/console/options/TestDiscoveryOptionsMixin.java:171: Note: [CanonicalAnnotationSyntax] Omit redundant syntax from annotation declarations
		@Option(names = {
		^
    (see https://error-prone.picnic.tech/bugpatterns/CanonicalAnnotationSyntax)
  Did you mean '@Option(names = "--exclude-methodname", paramLabel = "PATTERN", arity = "1", description = "Provide a regular expression to exclude those methods whose fully qualified names without parameters match. "'?
/Users/vincent.potucek/IdeaProjects/junit-framework/junit-platform-console/src/main/java/org/junit/platform/console/options/TestDiscoveryOptionsMixin.java:220: Note: [CanonicalAnnotationSyntax] Omit redundant syntax from annotation declarations
		@Option(names = {
		^
    (see https://error-prone.picnic.tech/bugpatterns/CanonicalAnnotationSyntax)
  Did you mean '@Option(names = "--config-resource", paramLabel = "PATH", arity = "1", description = "Set configuration parameters for test discovery and execution via a classpath resource. This option can be repeated.")'?
Refactoring changes were successfully applied to file:///Users/vincent.potucek/IdeaProjects/junit-framework/junit-platform-console/src/main/java/org/junit/platform/console/options/TestDiscoveryOptionsMixin.java, please check the refactored code and recompile.
> Task :junit-platform-console:shadowJar
> Task :junit-platform-console:jar SKIPPED
> Task :junit-platform-console-standalone:extractThirdPartyLicenses
> Task :junit-platform-console:javadoc FROM-CACHE
> Task :junit-platform-console:javadocJar
> Task :junit-platform-console:assemble
> Task :junit-platform-console-standalone:shadowJar
> Task :junit-platform-console-standalone:jar SKIPPED
> Task :junit-platform-console-standalone:javadoc NO-SOURCE
> Task :junit-platform-console-standalone:javadocJar
> Task :junit-platform-console-standalone:assemble

[Incubating] Problems report is available at: file:///Users/vincent.potucek/IdeaProjects/junit-framework/build/reports/problems/problems-report.html

Deprecated Gradle features were used in this build, making it incompatible with Gradle 10.

You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.

For more on this, please refer to https://docs.gradle.org/9.1.0/userguide/command_line_interface.html#sec:command_line_warnings in the Gradle documentation.

BUILD SUCCESSFUL in 7s
168 actionable tasks: 81 executed, 33 from cache, 54 up-to-date
Consider enabling configuration cache to speed up this build: https://docs.gradle.org/9.1.0/userguide/configuration_cache_enabling.html
12:32:08: Execution finished 'clean assemble'.

"-XepPatchLocation:IN_PLACE", // why only certain picnic rules apply?
"-XepPatchChecks:" +
"AddNullMarkedToPackageInfo," +
"AlwaysThrows," +
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For sure, we don’t need all of these, but technically or ideally, some definitely apply.

Continuing to do so is the natural outcome of the plugin being consistent—failing the build if something goes wrong—thus automating the process and reinforcing automation.

"OptionalOrElseGet",
"PrimitiveComparison",
"StaticImport",
"TimeZoneUsage",
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are failing and cannot be fixed through patching, which is somewhat of a mystery.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants